using System;
using System.Collections.Generic;
using System.Linq;

namespace NetMigration.Utilities
{
    public static class VersionFinder
    {
        public static int MaxVersion(this List<Type> migrationTypeList)
        {
            if(migrationTypeList.Count == 0)
            {
                return 0;
            }
            var versionList = new List<DbVersionAttribute>();
            migrationTypeList.ForEach(type =>
                                          {
                                              DbVersionAttribute dbVersionAttribute = type.GetDbVersion();
                                              if (dbVersionAttribute != null)
                                              {
                                                  versionList.Add(dbVersionAttribute);
                                              }
                                          });
            return versionList.Max<DbVersionAttribute, int>(versionAttribute => versionAttribute.Version);
        }

        public static List<Type> FindAllVersionLaterThan(this List<Type> migrationTypes, int currentVersion)
        {
            var foundList = migrationTypes.FindAll(type =>
                                              {
                                                  DbVersionAttribute dbVersionAttribute = type.GetDbVersion();
                                                  if (dbVersionAttribute != null)
                                                  {
                                                      return dbVersionAttribute.Version > currentVersion;
                                                  }
                                                  else
                                                  {
                                                      return false;
                                                  }
                                              });
            foundList.Sort(new VersionTypeComparer());

            return foundList;
        }

        public static List<Type> FindAllVersionInRange(this List<Type> migrationTypes, int left, int right)
        {
            var foundList = migrationTypes.FindAll(type =>
            {
                DbVersionAttribute dbVersionAttribute = type.GetDbVersion();
                if (dbVersionAttribute != null)
                {
                    return (dbVersionAttribute.Version > left) && (dbVersionAttribute.Version < right);
                }
                else
                {
                    return false;
                }
            });
            foundList.Sort(new VersionTypeComparer());

            return foundList;
        }

        private static DbVersionAttribute GetDbVersion(this Type type)
        {
            object[] attributes = type.GetCustomAttributes(
                typeof (DbVersionAttribute), false);
            if (attributes.Length > 0)
            {
                return (DbVersionAttribute) attributes[0];
            }
            return null;
        }

        private class VersionTypeComparer : IComparer<Type>
        {
            public int Compare(Type x, Type y)
            {
                return x.GetDbVersion().Version.CompareTo(y.GetDbVersion().Version);
            }
        }
    }
}